package com.turingoal.common.util.workfolw;

import java.io.Serializable;
import java.util.Map;
import org.activiti.engine.ActivitiException;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.impl.RepositoryServiceImpl;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.interceptor.Command;
import org.activiti.engine.impl.interceptor.CommandContext;
import org.activiti.engine.impl.persistence.entity.ExecutionEntity;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.persistence.entity.TaskEntity;
import org.activiti.engine.impl.pvm.process.ActivityImpl;

/**
 * AtiivitiJumpCommand
 */
public class AtiivitiJumpCommand implements Command<Object>, Serializable {

	private static final long serialVersionUID = 1L;
	private String executionId; // 流程ID
	private String targetActivitiId; // 跳转目标环节ID
	private String taskId; // 当前任务ID
	private Map<String, Object> variables;

	/**
	 * AtiivitiJumpCommand
	 */
	public AtiivitiJumpCommand(final String executionIdParm, final String targetActivitiIdParm, final String taskIdParm, final Map<String, Object> variablesParm) {
		this.executionId = executionIdParm;
		this.targetActivitiId = targetActivitiIdParm;
		this.variables = variablesParm;
		this.taskId = taskIdParm;
	}

	@Override
	public Object execute(final CommandContext commandContext) {
		if (executionId == null) {
			throw new ActivitiException("executionId is null");
		}
		if (targetActivitiId == null) {
			throw new ActivitiException("targetActivitiId is null!");
		}
		// 查找运行中 的Execution
		// ExecutionEntity execution = commandContext.getExecutionManager().findExecutionById(executionId);
		ExecutionEntity execution = commandContext.getExecutionEntityManager().findExecutionById(executionId);
		if (execution == null) {
			HistoricProcessInstance hai = Context.getProcessEngineConfiguration().getHistoryService().createHistoricProcessInstanceQuery().processInstanceId(executionId).singleResult();
			if (hai != null) {
				throw new ActivitiException("execution " + executionId + " has been completed at " + hai.getEndTime());
			} else {
				throw new ActivitiException("execution " + executionId + " doesn't exist");
			}
		}
		// 设置流程变量
		if (variables != null && !variables.isEmpty()) {
			execution.setVariables(variables);
		}
		// 查找流程定义
		String processDefinitionId = execution.getProcessDefinitionId();
		RepositoryServiceImpl rsi = (RepositoryServiceImpl) Context.getProcessEngineConfiguration().getRepositoryService();
		ProcessDefinitionEntity pde = (ProcessDefinitionEntity) rsi.getDeployedProcessDefinition(processDefinitionId);
		ActivityImpl targetActiviti = pde.findActivity(targetActivitiId);
		if (targetActiviti == null) {
			throw new ActivitiException("targetActiviti " + targetActiviti + " doesn't exist");
		}
		// 跳转
		try {
			execution.take(targetActiviti.getIncomingTransitions().iterator().next());
			// 删除当前任务
			// TaskEntity task = Context.getCommandContext().getTaskManager().findTaskById(taskId);
			TaskEntity task = Context.getCommandContext().getTaskEntityManager().findTaskById(taskId);
			if (task != null && !task.isDeleted()) {
				// Context.getCommandContext().getTaskManager().deleteTask(task, "reject", false);
				Context.getCommandContext().getTaskEntityManager().deleteTask(task, "reject", false);
			}
			return true;
		} catch (Exception e) {
			return false;
		}
	}
}